#include "ui/MainWindow.h"
#include "ui/ConfigPanel.h"
#include "ui/CodeEditor.h"
#include "core/ObfuscatorEngine.h"
#include "database/DatabaseManager.h"
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QActionGroup>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QTableWidget>
#include <QHeaderView>
#include <QTextEdit>
#include <QPlainTextEdit>
#include <QProgressBar>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QLineEdit>
#include <QInputDialog>
#include <QSplitter>
#include <QDockWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGroupBox>
#include <QFileDialog>
#include <QMessageBox>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QTextStream>
#include <QSyntaxHighlighter>
#include <QTextDocument>
#include <QTextCharFormat>
#include <QGraphicsDropShadowEffect>
#include <QCoreApplication>
#include <QApplication>
#include <QGuiApplication>
#include <QScreen>
#include <QDebug>
#include <QSettings>
#include <QTimer>
#include <QRegularExpression>
#include "ui/CustomSplitter.h"
#include "ui/CustomScrollView.h"
#include "utils/Theme.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_engine(std::make_unique<ObfuscatorEngine>())
{
    // 初始化屏幕参数
    QScreen *screen = QGuiApplication::primaryScreen();
    m_screenDPI = screen->logicalDotsPerInch();
    QRect screenGeometry = screen->availableGeometry();
    m_screenWidth = screenGeometry.width();
    m_screenHeight = screenGeometry.height();
    
    setupUi();
    
    // 初始化数据库
    DatabaseManager::instance().initialize();
    
    // 连接信号
    connect(m_engine.get(), &ObfuscatorEngine::progressUpdated,
            this, &MainWindow::onProgressUpdated);
    connect(m_engine.get(), &ObfuscatorEngine::obfuscationCompleted,
            this, &MainWindow::onObfuscationCompleted);
    connect(m_engine.get(), &ObfuscatorEngine::errorOccurred,
            this, &MainWindow::onErrorOccurred);
    
    // 设置时间更新定时器
    m_dateTimeTimer = new QTimer(this);
    connect(m_dateTimeTimer, &QTimer::timeout, this, &MainWindow::updateDateTime);
    m_dateTimeTimer->start(1000); // 每秒更新一次
    updateDateTime(); // 立即显示时间
}

MainWindow::~MainWindow() = default;

void MainWindow::setupUi()
{
    setWindowTitle("ObfuscatorPro - 代码混淆工具");
    setWindowIcon(QIcon(":/icons/app.png"));

    // 窗口大小 - 适应屏幕
    QScreen *screen = QGuiApplication::primaryScreen();
    QRect screenGeometry = screen->availableGeometry();
    int windowWidth = qMin(static_cast<int>(screenGeometry.width() * 0.9), 1600);
    int windowHeight = qMin(static_cast<int>(screenGeometry.height() * 0.85), 1000);
    resize(windowWidth, windowHeight);
    
    // 加载样式表
    loadStyleSheet();
    
    createMenuBar();
    createToolBar();
    createCentralWidget();
    createStatusBar();
}

void MainWindow::createMenuBar()
{
    QMenuBar *menuBar = this->menuBar();
    
    // 文件菜单
    QMenu *fileMenu = menuBar->addMenu("文件(&F)");
    QAction *openAction = fileMenu->addAction("打开项目(&O)");
    openAction->setShortcut(QKeySequence::Open);
    connect(openAction, &QAction::triggered, this, &MainWindow::onOpenProject);
    
    QAction *saveAction = fileMenu->addAction("保存配置(&S)");
    saveAction->setShortcut(QKeySequence::Save);
    connect(saveAction, &QAction::triggered, this, &MainWindow::onSaveProject);
    
    fileMenu->addSeparator();
    
    QAction *exportAction = fileMenu->addAction("导出映射表(&E)");
    connect(exportAction, &QAction::triggered, this, &MainWindow::onExportMappings);
    
    fileMenu->addSeparator();
    
    QAction *exitAction = fileMenu->addAction("退出(&X)");
    exitAction->setShortcut(QKeySequence::Quit);
    connect(exitAction, &QAction::triggered, this, &MainWindow::onExit);
    
    // 工具菜单
    QMenu *toolsMenu = menuBar->addMenu("工具(&T)");
    QAction *validateAction = toolsMenu->addAction("验证代码(&V)");
    connect(validateAction, &QAction::triggered, this, &MainWindow::onValidateCode);
    
    QAction *rollbackAction = toolsMenu->addAction("回滚(&R)");
    connect(rollbackAction, &QAction::triggered, this, &MainWindow::onRollback);
    
    toolsMenu->addSeparator();
    
    QAction *whitelistAction = toolsMenu->addAction("管理白名单(&W)");
    connect(whitelistAction, &QAction::triggered, this, &MainWindow::onManageWhitelist);
    
    // 查看菜单
    QMenu *viewMenu = menuBar->addMenu("查看(&V)");
    
    QAction *historyAction = viewMenu->addAction("混淆历史(&H)");
    connect(historyAction, &QAction::triggered, this, &MainWindow::onShowHistory);
    
    // 帮助菜单
    QMenu *helpMenu = menuBar->addMenu("帮助(&H)");
    QAction *aboutAction = helpMenu->addAction("关于(&A)");
    connect(aboutAction, &QAction::triggered, [this]() {
        QMessageBox::about(this, "关于 ObfuscatorPro",
            "ObfuscatorPro v1.0.0\n\n"
            "一个强大的iOS/Android代码混淆工具\n\n"
            "功能特性：\n"
            "• 类名、方法名、属性名混淆\n"
            "• 垃圾代码注入\n"
            "• 智能白名单管理\n"
            "• 混淆历史记录\n"
            "• 支持回滚操作");
    });
}

void MainWindow::createToolBar()
{
    QToolBar *toolBar = addToolBar("主工具栏");
    toolBar->setMovable(false);
    toolBar->setIconSize(QSize(20, 20));
    toolBar->setVisible(false);
}

void MainWindow::createCentralWidget()
{
    QWidget *centralWidget = new QWidget;
    setCentralWidget(centralWidget);
    centralWidget->setObjectName("centralWidget");
    
    QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget);
    mainLayout->setContentsMargins(8, 8, 8, 8);
    mainLayout->setSpacing(0);  // QSplitter will handle spacing
    
    // 创建主分割器用于水平布局
    QSplitter *mainSplitter = new CustomSplitter(Qt::Horizontal);
    mainSplitter->setHandleWidth(8);
    mainSplitter->setChildrenCollapsible(false);
    
    // === 第一个面板：混淆配置 ===
    QWidget *configPanel = new QWidget;
    configPanel->setObjectName("panelWidget");
    configPanel->setMinimumWidth(350);  // 配置面板需要更宽的最小宽度
    QVBoxLayout *configLayout = new QVBoxLayout(configPanel);
    configLayout->setContentsMargins(8, 8, 8, 8);
    configLayout->setSpacing(6);
    
    // 配置面板标题栏
    QWidget *configTitleBar = new QWidget;
    configTitleBar->setObjectName("titleBar");
    configTitleBar->setFixedHeight(44);
    QHBoxLayout *configTitleLayout = new QHBoxLayout(configTitleBar);
    configTitleLayout->setContentsMargins(12, 0, 12, 0);
    
    QLabel *configTitle = new QLabel("混淆配置");
    configTitle->setObjectName("titleLabel");
    configTitle->setFont(QFont(configTitle->font().family(), getResponsiveFontSize(11)));
    configTitleLayout->addWidget(configTitle);
    configTitleLayout->addStretch();
    
    configLayout->addWidget(configTitleBar);
    
    // 配置面板
    m_configPanel = new ConfigPanel;
    configLayout->addWidget(m_configPanel, 1);
    
    // 连接配置面板信号
    connect(m_configPanel, &ConfigPanel::requestExcludeFromProject, 
            this, &MainWindow::onRequestExcludeFromProject);
    
    // 进度条
    m_progressBar = new QProgressBar;
    m_progressBar->setVisible(false);
    m_progressBar->setTextVisible(true);
    m_progressBar->setFormat("%p% - %v/%m");
    configLayout->addWidget(m_progressBar);
    
    // 配置操作按钮组
    QWidget *configButtonsWidget = new QWidget;
    QVBoxLayout *configButtonsLayout = new QVBoxLayout(configButtonsWidget);
    configButtonsLayout->setContentsMargins(5, 8, 5, 0);
    configButtonsLayout->setSpacing(6);
    
    // 导入配置按钮
    QIcon importIcon;
    importIcon.addFile(":/icons/input.svg", QSize(), QIcon::Normal);
    importIcon.addFile(":/icons/input_gray.svg", QSize(), QIcon::Disabled);
    QPushButton *importConfigBtn = new QPushButton(importIcon, "导入配置");
    importConfigBtn->setToolTip("从文件导入混淆配置");
    importConfigBtn->setFixedHeight(28);
    importConfigBtn->setFont(QFont(importConfigBtn->font().family(), getResponsiveFontSize(9)));
    connect(importConfigBtn, &QPushButton::clicked, this, &MainWindow::onImportConfig);
    configButtonsLayout->addWidget(importConfigBtn);
    
    // 导出配置按钮
    QIcon exportIcon;
    exportIcon.addFile(":/icons/export.svg", QSize(), QIcon::Normal);
    exportIcon.addFile(":/icons/export.svg", QSize(), QIcon::Disabled);  // 使用同一个图标，Qt会自动变灰
    QPushButton *exportConfigBtn = new QPushButton(exportIcon, "导出配置");
    exportConfigBtn->setToolTip("将当前配置导出到文件");
    exportConfigBtn->setFixedHeight(28);
    exportConfigBtn->setFont(QFont(exportConfigBtn->font().family(), getResponsiveFontSize(9)));
    connect(exportConfigBtn, &QPushButton::clicked, this, &MainWindow::onExportConfig);
    configButtonsLayout->addWidget(exportConfigBtn);
    
    // 开始混淆按钮
    QIcon startIcon;
    startIcon.addFile(":/icons/start.svg", QSize(), QIcon::Normal);
    startIcon.addFile(":/icons/start_gary.svg", QSize(), QIcon::Disabled);
    m_startButton = new QPushButton(startIcon, "开始混淆");
    m_startButton->setEnabled(false);
    m_startButton->setProperty("success", true);
    m_startButton->setToolTip("开始执行代码混淆");
    m_startButton->setFixedHeight(28);
    m_startButton->setFont(QFont(m_startButton->font().family(), getResponsiveFontSize(9)));
    connect(m_startButton, &QPushButton::clicked, this, &MainWindow::onStartObfuscation);
    configButtonsLayout->addWidget(m_startButton);
    
    configLayout->addWidget(configButtonsWidget);
    
    // === 第二个面板：项目文件 ===
    QWidget *leftPanel = new QWidget;
    leftPanel->setObjectName("panelWidget");
    leftPanel->setMinimumWidth(220);  // 最小宽度保证可用性
    QVBoxLayout *leftLayout = new QVBoxLayout(leftPanel);
    leftLayout->setContentsMargins(8, 8, 8, 8);
    leftLayout->setSpacing(6);
    
    // 左侧标题
    QWidget *leftTitleBar = new QWidget;
    leftTitleBar->setObjectName("titleBar");
    leftTitleBar->setFixedHeight(44);
    QHBoxLayout *leftTitleLayout = new QHBoxLayout(leftTitleBar);
    leftTitleLayout->setContentsMargins(12, 0, 12, 0);
    
    QLabel *leftTitle = new QLabel("项目文件");
    leftTitle->setObjectName("titleLabel");
    leftTitle->setFont(QFont(leftTitle->font().family(), getResponsiveFontSize(11)));
    leftTitleLayout->addWidget(leftTitle);
    leftTitleLayout->addStretch();
    
    leftLayout->addWidget(leftTitleBar);
    
    // 工具栏按钮组
    QWidget *toolbarWidget = new QWidget;
    QVBoxLayout *toolbarLayout = new QVBoxLayout(toolbarWidget);
    toolbarLayout->setContentsMargins(0, 8, 0, 8);
    toolbarLayout->setSpacing(6);
    
    // 打开项目按钮
    QIcon openProjectIcon;
    openProjectIcon.addFile(":/icons/input.svg", QSize(), QIcon::Normal);
    openProjectIcon.addFile(":/icons/input_gray.svg", QSize(), QIcon::Disabled);
    QPushButton *openProjectBtn = new QPushButton(openProjectIcon, "打开项目");
    openProjectBtn->setToolTip("选择要混淆的项目目录");
    openProjectBtn->setFixedHeight(28);
    openProjectBtn->setFont(QFont(openProjectBtn->font().family(), getResponsiveFontSize(9)));
    connect(openProjectBtn, &QPushButton::clicked, this, &MainWindow::onOpenProject);
    toolbarLayout->addWidget(openProjectBtn);
    
    // 验证代码按钮
    QIcon validateIcon;
    validateIcon.addFile(":/icons/check.svg", QSize(), QIcon::Normal);
    validateIcon.addFile(":/icons/check_gray.svg", QSize(), QIcon::Disabled);
    m_validateBtn = new QPushButton(validateIcon, "验证代码");
    m_validateBtn->setToolTip("验证混淆后的代码");
    m_validateBtn->setEnabled(false);  // 默认禁用
    m_validateBtn->setFixedHeight(28);
    m_validateBtn->setFont(QFont(m_validateBtn->font().family(), getResponsiveFontSize(9)));
    connect(m_validateBtn, &QPushButton::clicked, this, &MainWindow::onValidateCode);
    toolbarLayout->addWidget(m_validateBtn);
    
    // 回滚按钮
    QIcon rollbackIcon;
    rollbackIcon.addFile(":/icons/back_black.svg", QSize(), QIcon::Normal);
    rollbackIcon.addFile(":/icons/back_black.svg", QSize(), QIcon::Disabled);  // Qt会自动变灰
    m_rollbackBtn = new QPushButton(rollbackIcon, "回滚代码");
    m_rollbackBtn->setToolTip("回滚到之前的版本");
    m_rollbackBtn->setEnabled(false);  // 默认禁用
    m_rollbackBtn->setFixedHeight(28);
    m_rollbackBtn->setFont(QFont(m_rollbackBtn->font().family(), getResponsiveFontSize(9)));
    connect(m_rollbackBtn, &QPushButton::clicked, this, &MainWindow::onRollback);
    toolbarLayout->addWidget(m_rollbackBtn);
    
    leftLayout->addWidget(toolbarWidget);
    
    // 搜索框
    QLineEdit *searchBox = new QLineEdit;
    searchBox->setPlaceholderText("搜索文件...");
    leftLayout->addWidget(searchBox);
    
    // 项目树
    m_projectTree = new QTreeWidget;
    m_projectTree->setAlternatingRowColors(true);
    m_projectTree->setAnimated(true);
    
    // 设置响应式字体大小
    QFont treeFont = m_projectTree->font();
    treeFont.setPointSize(getResponsiveFontSize(10));
    m_projectTree->setFont(treeFont);
    
    // 设置行高和初始样式
    m_projectTree->setUniformRowHeights(true);
    QFontMetrics fm(treeFont);
    int rowHeight = fm.height();
    QString initialStyle = QString(
        "QTreeWidget { font-size: 10pt; }"
        "QTreeWidget::item { height: %1px; }"
    ).arg(rowHeight);
    m_projectTree->setStyleSheet(initialStyle);
    
    // 创建自定义的header组件
    QWidget *treeHeaderWidget = new QWidget;
    QHBoxLayout *treeHeaderLayout = new QHBoxLayout(treeHeaderWidget);
    treeHeaderLayout->setContentsMargins(5, 2, 5, 2);
    treeHeaderLayout->setSpacing(5);
    
    QLabel *treeHeaderLabel = new QLabel("项目结构");
    treeHeaderLabel->setStyleSheet(QString("font-weight: bold; font-size: %1pt;").arg(getResponsiveFontSize(10)));
    treeHeaderLayout->addWidget(treeHeaderLabel);
    treeHeaderLayout->addStretch();
    
    // 添加字体大小控制按钮
    QPushButton *zoomOutBtn = new QPushButton;
    zoomOutBtn->setText("-");
    zoomOutBtn->setFixedSize(24, 24);
    zoomOutBtn->setToolTip("缩小字体");
    QFont btnFont("Arial", 14, QFont::Bold);
    zoomOutBtn->setFont(btnFont);
    zoomOutBtn->setStyleSheet(
        "QPushButton { "
        "    color: black; "
        "    background-color: #f0f0f0; "
        "    border: 1px solid #999; "
        "    border-radius: 3px; "
        "    padding: 0px; "
        "    text-align: center; "
        "} "
        "QPushButton:hover { "
        "    background-color: #e0e0e0; "
        "} "
        "QPushButton:pressed { "
        "    background-color: #d0d0d0; "
        "}"
    );
    connect(zoomOutBtn, &QPushButton::clicked, [this]() {
        QFont currentFont = m_projectTree->font();
        int currentSize = currentFont.pointSize();
        
        // 如果pointSize返回-1，使用pixelSize
        if (currentSize == -1) {
            currentSize = currentFont.pixelSize();
        }
        
        // 减小字体大小
        if (currentSize > 6) {
            QFont newFont(currentFont.family(), currentSize - 1);
            m_projectTree->setFont(newFont);
            
            // 更新样式表，包含字体大小和行高
            QFontMetrics fm(newFont);
            int rowHeight = fm.height();
            QString styleSheet = QString(
                "QTreeWidget { font-size: %1pt; }"
                "QTreeWidget::item { height: %2px; }"
            ).arg(currentSize - 1).arg(rowHeight);
            m_projectTree->setStyleSheet(styleSheet);
            
            m_projectTree->update(); // 强制重绘
            
            // 验证实际设置的字体大小
            QFont verifyFont = m_projectTree->font();
            qDebug() << "ZoomOut: " << currentSize << "->" << (currentSize - 1) 
                     << "Actual:" << verifyFont.pointSize() << "px:" << verifyFont.pixelSize();
        } else {
            qDebug() << "ZoomOut: Already at minimum size" << currentSize;
        }
    });
    treeHeaderLayout->addWidget(zoomOutBtn);
    
    QPushButton *zoomInBtn = new QPushButton;
    zoomInBtn->setText("+");
    zoomInBtn->setFixedSize(24, 24);
    zoomInBtn->setToolTip("放大字体");
    zoomInBtn->setFont(btnFont);
    zoomInBtn->setStyleSheet(
        "QPushButton { "
        "    color: black; "
        "    background-color: #f0f0f0; "
        "    border: 1px solid #999; "
        "    border-radius: 3px; "
        "    padding: 0px; "
        "    text-align: center; "
        "} "
        "QPushButton:hover { "
        "    background-color: #e0e0e0; "
        "} "
        "QPushButton:pressed { "
        "    background-color: #d0d0d0; "
        "}"
    );
    connect(zoomInBtn, &QPushButton::clicked, [this]() {
        QFont currentFont = m_projectTree->font();
        int currentSize = currentFont.pointSize();
        
        // 如果pointSize返回-1，使用pixelSize
        if (currentSize == -1) {
            currentSize = currentFont.pixelSize();
        }
        
        // 增大字体大小
        if (currentSize < 16) {
            QFont newFont(currentFont.family(), currentSize + 1);
            m_projectTree->setFont(newFont);
            
            // 更新样式表，包含字体大小和行高
            QFontMetrics fm(newFont);
            int rowHeight = fm.height();
            QString styleSheet = QString(
                "QTreeWidget { font-size: %1pt; }"
                "QTreeWidget::item { height: %2px; }"
            ).arg(currentSize + 1).arg(rowHeight);
            m_projectTree->setStyleSheet(styleSheet);
            
            m_projectTree->update(); // 强制重绘
            
            // 验证实际设置的字体大小
            QFont verifyFont = m_projectTree->font();
            qDebug() << "ZoomIn: " << currentSize << "->" << (currentSize + 1) 
                     << "Actual:" << verifyFont.pointSize() << "px:" << verifyFont.pixelSize();
        } else {
            qDebug() << "ZoomIn: Already at maximum size" << currentSize;
        }
    });
    treeHeaderLayout->addWidget(zoomInBtn);
    
    // 隐藏默认的树形控件header
    m_projectTree->setHeaderHidden(true);
    
    // 将自定义header和树组合
    QVBoxLayout *treeContainerLayout = new QVBoxLayout;
    treeContainerLayout->setContentsMargins(0, 0, 0, 0);
    treeContainerLayout->setSpacing(0);
    treeContainerLayout->addWidget(treeHeaderWidget);
    treeContainerLayout->addWidget(m_projectTree, 1);
    
    QWidget *treeContainer = new QWidget;
    treeContainer->setLayout(treeContainerLayout);
    
    connect(m_projectTree, &QTreeWidget::itemClicked,
            this, &MainWindow::onProjectItemClicked);
    leftLayout->addWidget(treeContainer, 1);
    
    // 快速操作按钮
    QWidget *quickActions = new QWidget;
    QHBoxLayout *quickLayout = new QHBoxLayout(quickActions);
    quickLayout->setContentsMargins(0, 0, 0, 0);
    
    QPushButton *refreshBtn = new QPushButton(QIcon(":/icons/refresh.svg"), "刷新");
    refreshBtn->setFixedHeight(24);
    connect(refreshBtn, &QPushButton::clicked, this, &MainWindow::updateProjectTree);
    quickLayout->addWidget(refreshBtn);
    
    // 折叠/展开切换按钮
    QPushButton *toggleExpandBtn = new QPushButton(QIcon(":/icons/up.svg"), "折叠");
    toggleExpandBtn->setFixedHeight(24);
    toggleExpandBtn->setProperty("expanded", true);  // 默认是展开状态
    
    connect(toggleExpandBtn, &QPushButton::clicked, [this, toggleExpandBtn]() {
        bool isExpanded = toggleExpandBtn->property("expanded").toBool();
        if (isExpanded) {
            m_projectTree->collapseAll();
            toggleExpandBtn->setText("展开");
            toggleExpandBtn->setIcon(QIcon(":/icons/down.svg"));
            toggleExpandBtn->setProperty("expanded", false);
        } else {
            m_projectTree->expandAll();
            toggleExpandBtn->setText("折叠");
            toggleExpandBtn->setIcon(QIcon(":/icons/up.svg"));
            toggleExpandBtn->setProperty("expanded", true);
        }
    });
    quickLayout->addWidget(toggleExpandBtn);
    
    leftLayout->addWidget(quickActions);
    
    // === 第三个面板：源码视图 ===
    QWidget *codePreviewPanel = new QWidget;
    codePreviewPanel->setObjectName("panelWidget");
    codePreviewPanel->setMinimumWidth(250);  // 最小宽度保证可读性
    QVBoxLayout *codePreviewLayout = new QVBoxLayout(codePreviewPanel);
    codePreviewLayout->setContentsMargins(8, 8, 8, 8);
    codePreviewLayout->setSpacing(6);
    
    // 源码视图标题栏
    QWidget *codePreviewTitleBar = new QWidget;
    codePreviewTitleBar->setObjectName("titleBar");
    codePreviewTitleBar->setFixedHeight(44);
    QHBoxLayout *codePreviewTitleLayout = new QHBoxLayout(codePreviewTitleBar);
    codePreviewTitleLayout->setContentsMargins(12, 0, 12, 0);
    
    QLabel *codePreviewTitle = new QLabel("源码视图");
    codePreviewTitle->setObjectName("titleLabel");
    codePreviewTitle->setFont(QFont(codePreviewTitle->font().family(), getResponsiveFontSize(11)));
    codePreviewTitleLayout->addWidget(codePreviewTitle);
    
    m_currentFileLabel = new QLabel("");
    m_currentFileLabel->setObjectName("filePathLabel");
    m_currentFileLabel->setStyleSheet("color: #888; font-size: 12px;");
    codePreviewTitleLayout->addWidget(m_currentFileLabel);
    codePreviewTitleLayout->addStretch();
    
    codePreviewLayout->addWidget(codePreviewTitleBar);
    
    // 源码预览文本框
    m_codePreview = new CodeEditor;
    m_codePreview->setObjectName("codePreview");
    m_codePreview->setReadOnly(true);
    m_codePreview->setPlaceholderText("选择一个代码文件以预览其内容...");
    codePreviewLayout->addWidget(m_codePreview, 1);
    
    // === 第四个面板：日志输出和混淆历史 ===
    QWidget *rightPanel = new QWidget;
    rightPanel->setObjectName("panelWidget");
    rightPanel->setMinimumWidth(280);  // 最小宽度保证日志和历史可读
    QVBoxLayout *rightLayout = new QVBoxLayout(rightPanel);
    rightLayout->setContentsMargins(8, 8, 8, 8);
    rightLayout->setSpacing(6);
    
    // 使用垂直分割器来分隔日志和历史
    QSplitter *rightSplitter = new CustomSplitter(Qt::Vertical);
    rightSplitter->setHandleWidth(20);
    
    // --- 上半部分：日志输出 ---
    QWidget *logWidget = new QWidget;
    QVBoxLayout *logLayout = new QVBoxLayout(logWidget);
    logLayout->setContentsMargins(0, 0, 0, 0);
    logLayout->setSpacing(4);
    
    // 右侧日志标题栏
    QWidget *logTitleBar = new QWidget;
    logTitleBar->setObjectName("titleBar");
    logTitleBar->setFixedHeight(44);
    QHBoxLayout *logTitleLayout = new QHBoxLayout(logTitleBar);
    logTitleLayout->setContentsMargins(12, 0, 12, 0);
    
    QLabel *logTitle = new QLabel("日志输出");
    logTitle->setObjectName("titleLabel");
    logTitle->setFont(QFont(logTitle->font().family(), getResponsiveFontSize(11)));
    logTitleLayout->addWidget(logTitle);
    logTitleLayout->addStretch();
    
    // 清空日志按钮
    QPushButton *clearLogBtn = new QPushButton("清空");
    clearLogBtn->setFixedHeight(20);
    clearLogBtn->setFont(QFont(clearLogBtn->font().family(), getResponsiveFontSize(8)));
    logTitleLayout->addWidget(clearLogBtn);
    logTitleLayout->setContentsMargins(12, 0, 0, 0);
    
    logLayout->addWidget(logTitleBar);
    
    // 状态指示器
    m_statusIndicator = new QLabel("就绪");
    m_statusIndicator->setObjectName("statusIndicator");
    m_statusIndicator->setProperty("status", "ready");
    logLayout->addWidget(m_statusIndicator);
    
    // 日志输出文本框
    m_logOutput = new QTextEdit;
    m_logOutput->setObjectName("logOutput");
    m_logOutput->setReadOnly(true);
    logLayout->addWidget(m_logOutput, 1);
    
    // 连接清空日志按钮
    connect(clearLogBtn, &QPushButton::clicked, [this]() {
        m_logOutput->clear();
        m_logOutput->append(QString("[%1] 日志已清空")
            .arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
    });
    
    // --- 下半部分：混淆历史 ---
    QWidget *historyWidget = new QWidget;
    QVBoxLayout *historyLayout = new QVBoxLayout(historyWidget);
    historyLayout->setContentsMargins(0, 0, 0, 0);
    historyLayout->setSpacing(4);
    
    // 历史标题栏
    QWidget *historyTitleBar = new QWidget;
    historyTitleBar->setObjectName("titleBar");
    historyTitleBar->setFixedHeight(40);
    QHBoxLayout *historyTitleLayout = new QHBoxLayout(historyTitleBar);
    historyTitleLayout->setContentsMargins(12, 0, 0, 0);  // 右边距设为0
    
    QLabel *historyTitle = new QLabel("混淆历史");
    historyTitle->setObjectName("titleLabel");
    historyTitle->setFont(QFont(historyTitle->font().family(), getResponsiveFontSize(11)));
    historyTitleLayout->addWidget(historyTitle);
    historyTitleLayout->addStretch();
    
    // 刷新历史按钮
    QPushButton *refreshHistoryBtn = new QPushButton("刷新");
    refreshHistoryBtn->setFixedHeight(20);
    refreshHistoryBtn->setFont(QFont(refreshHistoryBtn->font().family(), getResponsiveFontSize(8)));
    connect(refreshHistoryBtn, &QPushButton::clicked, this, &MainWindow::updateHistoryTable);
    historyTitleLayout->addWidget(refreshHistoryBtn);
    
    // 历史记录表格
    m_historyTable = new QTableWidget;
    m_historyTable->setColumnCount(5);
    m_historyTable->setHorizontalHeaderLabels({"版本ID", "时间", "类", "属性", "方法"});
    m_historyTable->setAlternatingRowColors(true);
    m_historyTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_historyTable->horizontalHeader()->setStretchLastSection(true);
    // 禁用表格自身滚动条，改由自定义滚动容器负责
    m_historyTable->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_historyTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_historyTable->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);

    // 使用自定义滚动视图容纳历史内容（标题+表格）
    QWidget *historyContent = new QWidget;
    QVBoxLayout *historyContentLayout = new QVBoxLayout(historyContent);
    historyContentLayout->setContentsMargins(0, 0, 0, 0);
    historyContentLayout->setSpacing(4);
    historyContentLayout->addWidget(historyTitleBar);
    historyContentLayout->addWidget(m_historyTable);

    CustomScrollView *historyScroll = new CustomScrollView;
    historyScroll->setContentWidget(historyContent);
    historyLayout->addWidget(historyScroll, 1);
    
    // 添加到分割器
    rightSplitter->addWidget(logWidget);
    rightSplitter->addWidget(historyWidget);
    rightSplitter->setStretchFactor(0, 3);  // 日志占3份
    rightSplitter->setStretchFactor(1, 2);  // 历史占2份
    
    rightLayout->addWidget(rightSplitter, 1);
    
    // === 添加四个面板到分割器 ===
    mainSplitter->addWidget(configPanel);       // 第一个：混淆配置
    mainSplitter->addWidget(leftPanel);         // 第二个：项目文件
    mainSplitter->addWidget(codePreviewPanel);  // 第三个：源码视图
    mainSplitter->addWidget(rightPanel);        // 第四个：日志输出
    
    // 设置初始比例（根据屏幕大小自适应）
    QScreen *screen = QGuiApplication::primaryScreen();
    QRect screenGeometry = screen->availableGeometry();
    int screenWidth = screenGeometry.width();
    
    if (screenWidth < 1200) {
        // 小屏幕：紧凑布局
        mainSplitter->setSizes({350, 200, 250, 200});
    } else if (screenWidth < 1600) {
        // 中等屏幕：平衡布局
        mainSplitter->setSizes({400, 250, 300, 350});
    } else {
        // 大屏幕：宽松布局
        mainSplitter->setSizes({450, 300, 400, 450});
    }
    
    // 将分割器添加到主布局
    mainLayout->addWidget(mainSplitter);

    // 连接搜索功能
    connect(searchBox, &QLineEdit::textChanged, this, [this](const QString &text) {
        filterProjectTree(m_projectTree->invisibleRootItem(), text);
    });
    
    // 初始化日志
    m_logOutput->append(QString("[%1] ObfuscatorPro 已启动，等待加载项目...")
        .arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
}

void MainWindow::createStatusBar()
{
    QStatusBar *statusBar = this->statusBar();
    
    // 左侧时间显示
    m_dateTimeLabel = new QLabel();
    m_dateTimeLabel->setObjectName("dateTimeLabel");
    statusBar->addWidget(m_dateTimeLabel);
    
    // 中间状态信息
    m_statusLabel = new QLabel("");
    m_statusLabel->setProperty("class", "subheading");
    statusBar->addWidget(m_statusLabel, 1);
}

void MainWindow::onOpenProject()
{
    QString dir = QFileDialog::getExistingDirectory(this, 
        "选择项目目录", 
        QDir::homePath(),
        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    
    if (!dir.isEmpty()) {
        loadProject(dir);
    }
}

void MainWindow::onSaveProject()
{
    // 保存当前配置
    QString fileName = QFileDialog::getSaveFileName(this,
        "保存配置文件",
        QDir::homePath() + "/obfuscator_config.json",
        "JSON Files (*.json)");
    
    if (!fileName.isEmpty()) {
        // 保存配置到文件
        QJsonObject config = m_configPanel->getConfig();
        QJsonDocument doc(config);
        
        QFile file(fileName);
        if (file.open(QIODevice::WriteOnly)) {
            file.write(doc.toJson());
            file.close();
            showMessage("配置已保存");
        }
    }
}

void MainWindow::onExportMappings()
{
    QString fileName = QFileDialog::getSaveFileName(this,
        "导出映射表",
        QDir::homePath() + "/mappings.csv",
        "CSV Files (*.csv)");
    
    if (!fileName.isEmpty()) {
        if (m_engine->exportMappings(fileName)) {
            showMessage("映射表已导出");
        } else {
            QMessageBox::warning(this, "导出失败", "无法导出映射表");
        }
    }
}

void MainWindow::onExit()
{
    close();
}

void MainWindow::onImportConfig()
{
    QString fileName = QFileDialog::getOpenFileName(this,
        "导入配置文件",
        QDir::homePath(),
        "JSON Files (*.json)");
    
    if (!fileName.isEmpty()) {
        QFile file(fileName);
        if (file.open(QIODevice::ReadOnly)) {
            QByteArray data = file.readAll();
            file.close();
            
            QJsonDocument doc = QJsonDocument::fromJson(data);
            if (!doc.isNull() && doc.isObject()) {
                QJsonObject config = doc.object();
                m_configPanel->loadConfig(config);
                showMessage("配置已导入");
                
                m_logOutput->append(QString("[%1] 导入配置文件: %2")
                    .arg(QDateTime::currentDateTime().toString("hh:mm:ss"))
                    .arg(fileName));
            } else {
                QMessageBox::warning(this, "导入失败", "配置文件格式无效");
            }
        } else {
            QMessageBox::warning(this, "导入失败", "无法打开配置文件");
        }
    }
}

void MainWindow::onExportConfig()
{
    QString fileName = QFileDialog::getSaveFileName(this,
        "导出配置文件",
        QDir::homePath() + "/obfuscator_config.json",
        "JSON Files (*.json)");
    
    if (!fileName.isEmpty()) {
        QJsonObject config = m_configPanel->getConfig();
        QJsonDocument doc(config);
        
        QFile file(fileName);
        if (file.open(QIODevice::WriteOnly)) {
            file.write(doc.toJson(QJsonDocument::Indented));
            file.close();
            showMessage("配置已导出");
            
            m_logOutput->append(QString("[%1] 导出配置文件: %2")
                .arg(QDateTime::currentDateTime().toString("hh:mm:ss"))
                .arg(fileName));
        } else {
            QMessageBox::warning(this, "导出失败", "无法保存配置文件");
        }
    }
}

void MainWindow::onStartObfuscation()
{
    if (m_projectPath.isEmpty()) {
        QMessageBox::warning(this, "警告", "请先打开项目");
        return;
    }
    
    // 获取配置
    ObfuscationConfig config = m_configPanel->getObfuscationConfig();
    
    // 设置引擎配置
    m_engine->setProjectPath(m_projectPath);
    m_engine->setConfig(config);
    
    // 禁用按钮
    m_startButton->setEnabled(false);
    m_progressBar->setVisible(true);
    
    // 记录开始时间
    m_logOutput->append(QString("[%1] 开始混淆处理...")
        .arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
    
    // 开始混淆
    m_engine->obfuscate();
}

void MainWindow::onValidateCode()
{
    if (m_engine->validate()) {
        QMessageBox::information(this, "验证成功", "代码验证通过");
    } else {
        QMessageBox::warning(this, "验证失败", "代码验证失败，请检查混淆结果");
    }
}

void MainWindow::onRollback()
{
    // 显示版本选择对话框
    bool ok;
    QString versionId = QInputDialog::getText(this, "回滚",
        "请输入要回滚到的版本ID:", QLineEdit::Normal, "", &ok);
    
    if (ok && !versionId.isEmpty()) {
        if (m_engine->rollback(versionId)) {
            showMessage("回滚成功");
            updateProjectTree();
        } else {
            QMessageBox::warning(this, "回滚失败", "无法回滚到指定版本");
        }
    }
}

void MainWindow::onShowHistory()
{
    updateHistoryTable();
}

void MainWindow::onManageWhitelist()
{
    // 显示白名单管理对话框
    QMessageBox::information(this, "白名单管理", "白名单管理功能正在开发中");
}

void MainWindow::onProgressUpdated(int percentage, const QString &message)
{
    m_progressBar->setValue(percentage);
    m_statusLabel->setText(message);
    
    // 更新状态指示器颜色
    if (m_statusIndicator) {
        m_statusIndicator->setText("处理中...");
        m_statusIndicator->setProperty("status", "processing");
        m_statusIndicator->style()->polish(m_statusIndicator);
    }
    
    m_logOutput->append(QString("[%1] %2")
        .arg(QDateTime::currentDateTime().toString("hh:mm:ss"))
        .arg(message));
}

void MainWindow::onObfuscationCompleted(const ObfuscationResult &result)
{
    m_progressBar->setVisible(false);
    m_startButton->setEnabled(true);
    
    // 更新状态指示器
    if (m_statusIndicator) {
        m_statusIndicator->setText("完成");
        m_statusIndicator->setProperty("status", "completed");
        m_statusIndicator->style()->polish(m_statusIndicator);
    }
    
    if (result.success) {
        QString message = QString("混淆完成！\n"
            "类重命名: %1\n"
            "属性重命名: %2\n"
            "方法重命名: %3\n"
            "垃圾代码注入: %4")
            .arg(result.classesRenamed)
            .arg(result.propertiesRenamed)
            .arg(result.methodsRenamed)
            .arg(result.trashCodeInjected);
        
        QMessageBox::information(this, "混淆完成", message);
        
        // 保存到数据库
        QString versionId = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
        QJsonObject record;
        record["version_id"] = versionId;
        record["project_path"] = m_projectPath;
        record["status"] = "success";
        
        QJsonObject stats;
        stats["classes"] = result.classesRenamed;
        stats["properties"] = result.propertiesRenamed;
        stats["methods"] = result.methodsRenamed;
        stats["trash_code"] = result.trashCodeInjected;
        record["statistics"] = stats;
        
        DatabaseManager::instance().saveObfuscationRecord(record);
        
        // 保存映射关系
        QJsonObject mappings;
        for (auto it = result.mappings.begin(); it != result.mappings.end(); ++it) {
            mappings[it.key()] = it.value();
        }
        DatabaseManager::instance().saveMappings(versionId, mappings);
        
        // 更新历史表
        updateHistoryTable();
    } else {
        QMessageBox::critical(this, "混淆失败", result.errorMessage);
    }
}

void MainWindow::onErrorOccurred(const QString &error)
{
    m_progressBar->setVisible(false);
    m_startButton->setEnabled(true);
    
    QMessageBox::critical(this, "错误", error);
    m_logOutput->append(QString("[%1] 错误: %2")
        .arg(QDateTime::currentDateTime().toString("hh:mm:ss"))
        .arg(error));
}

void MainWindow::onProjectItemClicked(QTreeWidgetItem *item, int column)
{
    Q_UNUSED(column)
    // 处理项目树点击事件
    QString filePath = item->data(0, Qt::UserRole).toString();
    if (!filePath.isEmpty()) {
        m_logOutput->append("选中文件: " + filePath);
        
        // 检查是否是代码文件
        QFileInfo fileInfo(filePath);
        if (fileInfo.isFile()) {
            // 支持的代码文件扩展名
            QStringList codeExtensions = {
                "h", "hpp", "hxx", "c", "cpp", "cc", "cxx", "m", "mm",
                "java", "kt", "swift", "py", "js", "ts", "jsx", "tsx",
                "sh", "bash", "zsh", "xml", "json", "yaml", "yml"
            };
            
            QString extension = fileInfo.suffix().toLower();
            if (codeExtensions.contains(extension)) {
                // 读取并显示文件内容
                QFile file(filePath);
                if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
                    QTextStream stream(&file);
                    QString content = stream.readAll();
                    file.close();
                    
                    // 显示在源码预览窗口
                    m_codePreview->setPlainText(content);
                    
                    // 更新当前文件标签，显示相对路径
                    QString relativePath = filePath;
                    if (filePath.startsWith(m_projectPath)) {
                        relativePath = filePath.mid(m_projectPath.length() + 1);
                    }
                    m_currentFileLabel->setText(relativePath);
                    
                    // 设置语言类型以启用语法高亮
                    m_codePreview->setLanguage(extension);
                } else {
                    m_codePreview->setPlainText("无法读取文件: " + filePath);
                    m_currentFileLabel->setText("");
                }
            } else {
                // 非代码文件，清空预览
                m_codePreview->clear();
                m_codePreview->setPlaceholderText("选中的文件不是代码文件");
                m_currentFileLabel->setText("");
            }
        } else {
            // 选中的是目录，清空预览
            m_codePreview->clear();
            m_codePreview->setPlaceholderText("选择一个代码文件以预览其内容...");
            m_currentFileLabel->setText("");
        }
    }
}

void MainWindow::loadProject(const QString &path)
{
    m_projectPath = path;
    m_engine->setProjectPath(path);
    
    setWindowTitle(QString("ObfuscatorPro - %1").arg(QFileInfo(path).fileName()));
    
    updateProjectTree();
    updateHistoryTable();
    
    m_startButton->setEnabled(true);
    m_validateBtn->setEnabled(true);  // 启用验证代码按钮
    m_rollbackBtn->setEnabled(true);  // 启用回滚代码按钮
    m_configPanel->setProjectLoaded(true);  // 启用配置面板的项目相关功能
    
    showMessage("项目已加载");
}

void MainWindow::updateProjectTree()
{
    m_projectTree->clear();
    
    if (m_projectPath.isEmpty()) {
        return;
    }
    
    QTreeWidgetItem *rootItem = new QTreeWidgetItem(m_projectTree);
    rootItem->setText(0, QFileInfo(m_projectPath).fileName());
    rootItem->setIcon(0, style()->standardIcon(QStyle::SP_DirIcon));
    rootItem->setData(0, Qt::UserRole, m_projectPath);
    
    // 递归加载项目目录
    loadProjectDirectory(rootItem, m_projectPath);
    
    m_projectTree->expandAll();
}

void MainWindow::loadProjectDirectory(QTreeWidgetItem *parent, const QString &path)
{
    QDir dir(path);
    QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot,
                                            QDir::DirsFirst | QDir::Name);
    
    for (const QFileInfo &info : list) {
        // 跳过隐藏文件和特定目录
        if (info.fileName().startsWith(".") ||
            info.fileName() == "build" ||
            info.fileName() == "__pycache__" ||
            info.fileName() == "node_modules") {
            continue;
        }
        
        QTreeWidgetItem *item = new QTreeWidgetItem(parent);
        item->setText(0, info.fileName());
        item->setData(0, Qt::UserRole, info.absoluteFilePath());
        
        if (info.isDir()) {
            item->setIcon(0, style()->standardIcon(QStyle::SP_DirIcon));
            // 递归加载子目录
            loadProjectDirectory(item, info.absoluteFilePath());
        } else {
            item->setIcon(0, style()->standardIcon(QStyle::SP_FileIcon));
        }
    }
}

void MainWindow::updateHistoryTable()
{
    m_historyTable->setRowCount(0);
    
    QJsonArray history = DatabaseManager::instance().getObfuscationHistory(20);
    
    for (const QJsonValue &value : history) {
        QJsonObject record = value.toObject();
        int row = m_historyTable->rowCount();
        m_historyTable->insertRow(row);
        
        m_historyTable->setItem(row, 0, new QTableWidgetItem(record["version_id"].toString()));
        m_historyTable->setItem(row, 1, new QTableWidgetItem(record["timestamp"].toString()));
        
        QJsonObject stats = record["statistics"].toObject();
        m_historyTable->setItem(row, 2, new QTableWidgetItem(QString::number(stats["classes"].toInt())));
        m_historyTable->setItem(row, 3, new QTableWidgetItem(QString::number(stats["properties"].toInt())));
        m_historyTable->setItem(row, 4, new QTableWidgetItem(QString::number(stats["methods"].toInt())));
    }
    
    m_historyTable->resizeColumnsToContents();
}

void MainWindow::showMessage(const QString &message, int timeout)
{
    statusBar()->showMessage(message, timeout);
}

void MainWindow::loadStyleSheet()
{
    // 加载QSS
    QFile qssFile(":/styles/elegant.qss");
    if (!qssFile.open(QFile::ReadOnly)) {
        qDebug() << "Failed to load theme file";
        return;
    }
    QString styleSheet = QLatin1String(qssFile.readAll());
    qssFile.close();

    // 使用集中定义的主题颜色占位符映射
    const QMap<QString, QString> placeholdersToHex = Theme::placeholdersToHex();
    for (auto it = placeholdersToHex.constBegin(); it != placeholdersToHex.constEnd(); ++it) {
        styleSheet.replace(it.key(), it.value());
    }

    if (QApplication *app = qobject_cast<QApplication*>(QCoreApplication::instance())) {
        app->setStyleSheet(styleSheet);
    }
    qDebug() << "Theme loaded successfully: elegant (placeholders)";
}


bool MainWindow::filterProjectTree(QTreeWidgetItem *item, const QString &text)
{
    if (!item) return false;
    
    bool hasVisibleChild = false;
    
    for (int i = 0; i < item->childCount(); ++i) {
        QTreeWidgetItem *child = item->child(i);
        bool childVisible = filterProjectTree(child, text);
        hasVisibleChild = hasVisibleChild || childVisible;
    }
    
    bool matches = text.isEmpty() || 
                   item->text(0).contains(text, Qt::CaseInsensitive);
    
    bool visible = matches || hasVisibleChild;
    item->setHidden(!visible);
    
    if (visible && !text.isEmpty() && item->parent()) {
        item->parent()->setExpanded(true);
    }
    
    return visible;
}

void MainWindow::updateDateTime()
{
    QDateTime now = QDateTime::currentDateTime();
    
    // 获取星期几
    QStringList weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
    int dayOfWeek = now.date().dayOfWeek();
    if (dayOfWeek == 7) dayOfWeek = 0; // Qt中周日是7，转换为0
    
    QString dateTimeStr = now.toString("yyyy-MM-dd HH:mm:ss") + " " + weekDays[dayOfWeek];
    m_dateTimeLabel->setText(dateTimeStr);
}

void MainWindow::onRequestExcludeFromProject()
{
    // 获取当前选中的项目树节点
    QTreeWidgetItem *currentItem = m_projectTree->currentItem();
    if (!currentItem) {
        QMessageBox::information(this, "提示", "请先在项目树中选择一个文件夹");
        return;
    }
    
    // 获取路径
    QString filePath = currentItem->data(0, Qt::UserRole).toString();
    if (filePath.isEmpty()) {
        filePath = currentItem->text(0);
    }
    
    // 如果是文件，获取其父目录
    QFileInfo fileInfo(filePath);
    QString relativePath;
    
    if (fileInfo.isFile()) {
        // 如果选中的是文件，使用其父目录
        relativePath = fileInfo.dir().dirName() + "/";
    } else {
        // 如果是目录，直接使用
        relativePath = fileInfo.fileName() + "/";
    }
    
    // 添加到配置面板
    m_configPanel->addExcludePath(relativePath);
}

void MainWindow::onWindowResize()
{
    // QSplitter handles panel resizing automatically
    // No need for manual width adjustments
}

void MainWindow::updateButtonSizes()
{
    // Button sizes are now fixed and no longer dynamically adjusted
    // QSplitter handles the responsive layout
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    // 调用基类的 resizeEvent
    QMainWindow::resizeEvent(event);
}

int MainWindow::getResponsiveFontSize(int baseSize) const
{
    // 根据屏幕DPI和分辨率计算合适的字体大小
    // 标准DPI为96，标准分辨率为1920x1080
    const qreal standardDPI = 96.0;
    const int standardWidth = 1920;
    
    // DPI缩放因子
    qreal dpiScale = m_screenDPI / standardDPI;
    
    // 分辨率缩放因子
    qreal resolutionScale = static_cast<qreal>(m_screenWidth) / standardWidth;
    
    // 综合缩放因子（使用较小的值以避免字体过大）
    qreal scale = qMin(dpiScale, resolutionScale);
    
    // 限制缩放范围
    scale = qBound(0.8, scale, 1.5);
    
    return qRound(baseSize * scale);
}